<?php
declare(strict_types=1);

namespace app\controller\user;

use app\controller\BaseController;
use app\model\{User, MerchantApplication};
use app\service\{LogService, WechatService, SmsService};
use think\facade\{Cache, Validate, Log};
use think\Request;

class AuthController extends BaseController
{
    /**
     * 微信小程序登录
     */
    public function miniLogin(Request $request)
    {
        try {
            $params = $request->post();
            
            // 参数验证
            $validate = Validate::rule([
                'code' => 'require',
                'merchant_id' => 'require|number'
            ]);
            
            if (!$validate->check($params)) {
                return $this->error($validate->getError());
            }
            
            // 获取商家小程序配置
            $app = MerchantApplication::where([
                'merchant_id' => $params['merchant_id'],
                'application_type' => 1, // 微信小程序
                'status' => 1
            ])->find();
            
            if (!$app) {
                return $this->error('商家小程序未配置');
            }
            
            // 获取openid
            $wechatService = new WechatService($app);
            $session = $wechatService->code2Session($params['code']);
            
            if (!isset($session['openid'])) {
                return $this->error('登录失败');
            }
            
            // 查找或创建用户
            $user = User::where([
                'merchant_id' => $params['merchant_id'],
                'openid' => $session['openid']
            ])->find();
            
            if (!$user) {
                $user = User::create([
                    'merchant_id' => $params['merchant_id'],
                    'openid' => $session['openid'],
                    'unionid' => $session['unionid'] ?? '',
                    'create_time' => date('Y-m-d H:i:s')
                ]);
            }
            
            // 生成token
            $token = $this->createToken($user->id, $params['merchant_id']);
            
            return $this->success([
                'token' => $token,
                'user_info' => $user
            ]);
            
        } catch (\Exception $e) {
            LogService::error('AuthController', sprintf(
                'Mini login failed: %s',
                $e->getMessage()
            ));
            return $this->error('登录失败');
        }
    }

    /**
     * 小程序解密手机号
     */
    public function  decryptPhone(){
        echo 2222;die;
    }
    
    /**
     * 获取公众号授权链接
     */
    public function getMpAuthUrl(Request $request)
    {
        try {
            $validate = Validate::rule([
                'redirect_uri' => 'require',
                'merchant_id' => 'require|number'
            ]);
            
            $params = $request->param();
            if (!$validate->check($params)) {
                return $this->error($validate->getError());
            }

            // 获取商家公众号配置
            $app = MerchantApplication::where([
                'merchant_id' => $params['merchant_id'],
                'application_type' => 2, // 公众号
                'status' => 1
            ])->find();
            
            if (!$app) {
                return $this->error('商家公众号未配置');
            }

            // 生成state参数,用于防止CSRF攻击
            $state = md5(uniqid(mt_rand(), true));
            Cache::set('mp_auth_state_'.$state, [
                'redirect_uri' => $params['redirect_uri'],
                'merchant_id' => $params['merchant_id']
            ], 600);

            // 获取授权链接
            $wechatService = new WechatService($app);
            $authUrl = $wechatService->getMpAuthUrl($state);

            return $this->success('获取成功', [
                'auth_url' => $authUrl
            ]);
        } catch (\Exception $e) {
            return $this->error('获取授权链接失败:'.$e->getMessage());
        }
    }

    /**
     * 公众号授权登录回调
     */
    public function mpLogin(Request $request)
    {
        try {
            $code = $request->param('code');
            $state = $request->param('state');
            
            if (!$code || !$state) {
                return $this->error('参数错误');
            }

            // 验证state,防止CSRF攻击
            $cacheData = Cache::pull('mp_auth_state_'.$state);
            if (!$cacheData) {
                return $this->error('state已过期或不存在');
            }

            // 获取商家公众号配置
            $app = MerchantApplication::where([
                'merchant_id' => $cacheData['merchant_id'],
                'application_type' => 2,
                'status' => 1
            ])->find();
            
            if (!$app) {
                return $this->error('商家公众号未配置');
            }

            // 通过code获取access_token和openid
            $wechatService = new WechatService($app);
            $result = $wechatService->getMpAccessToken($code);
            
            if (!isset($result['openid'])) {
                return $this->error('获取openid失败');
            }

            // 获取用户信息
            $userInfo = $wechatService->getMpUserInfo($result['access_token'], $result['openid']);
            if (!$userInfo) {
                return $this->error('获取用户信息失败');
            }

            // 查找或创建用户
            $user = User::where([
                'merchant_id' => $cacheData['merchant_id'],
                'mp_openid' => $result['openid']
            ])->find();
            
            if (!$user) {
                $user = User::create([
                    'merchant_id' => $cacheData['merchant_id'],
                    'mp_openid' => $result['openid'],
                    'nickname' => $userInfo['nickname'],
                    'avatar' => $userInfo['headimgurl'],
                    'create_time' => date('Y-m-d H:i:s')
                ]);
            }

            // 生成token
            $token = $this->generateToken($user->id);

            // 重定向到前端页面,并带上token参数
            $redirectUri = $cacheData['redirect_uri'];
            $redirectUri .= (strpos($redirectUri, '?') !== false ? '&' : '?') . 'token=' . $token;
            return redirect($redirectUri);

        } catch (\Exception $e) {
            return $this->error('登录失败:'.$e->getMessage());
        }
    }
    
    /**
     * 发送手机验证码
     */
    public function sendSmsCode(Request $request)
    {
        try {
            $params = $this->validate($request->post(), [
                'mobile' => 'require|mobile',
                'merchant_id' => 'require|number'
            ]);
            
            // 检查发送频率限制
            $cacheKey = "sms_limit_{$params['mobile']}";
            if (Cache::get($cacheKey)) {
                return $this->error('发送太频繁，请稍后再试');
            }
            
            // 生成验证码
            $code = mt_rand(100000, 999999);
            
            // 调用短信服务发送验证码
            $smsService = new SmsService($params['merchant_id']);
            $result = $smsService->sendCode($params['mobile'], $code);
            
            if (!$result) {
                return $this->error('短信发送失败');
            }
            
            // 将验证码存入缓存
            Cache::set("sms_code_{$params['mobile']}", $code, 300);  // 5分钟有效期
            Cache::set($cacheKey, 1, 60);  // 1分钟内不能重复发送
            
            return $this->success('验证码发送成功');
            
        } catch (\Exception $e) {
            Log::error('发送验证码失败', [
                'error' => $e->getMessage(),
                'params' => $request->post()
            ]);
            return $this->error('发送失败：' . $e->getMessage());
        }
    }

    /**
     * 手机号验证码登录
     */
    public function mobileLogin(Request $request)
    {
        try {
            $params = $this->validate($request->post(), [
                'mobile' => 'require|mobile',
                'code' => 'require|number|length:6'
            ]);
            
            // 验证码校验
            $cacheKey = "sms_code_{$params['mobile']}";
            $cachedCode = Cache::get($cacheKey);
            
            if (!$cachedCode || $cachedCode != $params['code']) {
                return $this->error('验证码错误或已过期');
            }
            
            // 获取或创建用户
            $user = User::where('mobile', $params['mobile'])->find();
            if (!$user) {
                $user = User::create([
                    'mobile' => $params['mobile'],
                    'create_time' => date('Y-m-d H:i:s')
                ]);
            }
            
            // 生成 token
            $token = $this->createToken($user->id);
            
            // 清除验证码缓存
            Cache::delete($cacheKey);
            
            return $this->success('登录成功', [
                'token' => $token,
                'user' => $user
            ]);
            
        } catch (\Exception $e) {
            Log::error('手机号登录失败: ' . $e->getMessage());
            return $this->error('登录失败：' . $e->getMessage());
        }
    }
} 